#include <iostream>
#include <pthread.h>
#include <functional>
#include <string>
using namespace std;
class Thread
{
    typedef std::function<void *(void *)> func_t;

private:
    static void *start_routine(void *arg)
    {
        Thread *th = static_cast<Thread *>(arg);
        th->callback(th->_arg);
    }
    void *callback(void *arg)
    {
        return _func(arg);
    }

public:
    void start(func_t func, void *arg = nullptr)
    {
        _func = func;
        _arg = arg;
        pthread_create(&_tid, nullptr, start_routine, this);
    }
    void join()
    {
        pthread_join(_tid, nullptr);
    }
    ~Thread()
    {
        join();
    }

private:
    func_t _func;
    pthread_t _tid;
    void *_arg;
};